#include <unistd.h>
#include "base/cmd_flags.h"
#include "base/init.h"
#include "base/logging.h"
#include "net/rpc/rpcmessage.pb.h"
#include "net/rpc/rpc_service.h"
#include "net/rpc/rpc_channel.h"

DEFINE_int32(port, 5678, "");

/*
class MyService : public RpcService {
  public:
  MyService(int port) : RpcService(port) {
  }
  virtual void Process(const string& name, const string& request,
                       string* response, RPC* rpc) {
    Test t;
    t.ParseFromString(request);
    t.set_output(t.input() + 1);
    *response = t.SerializeAsString();
  }
};*/

class ExampleSearchService : public TestService {
 public:
  virtual void Search(google::protobuf::RpcController* controller,
              const Test* request,
              Test* response,
              Closure* done) {
    response->set_output(request->input() + 1);
    if (done) done->Run();
  }
  virtual void Search2(google::protobuf::RpcController* controller,
              const Test* request,
              Test* response,
              Closure* done) {
    sleep(5);
    response->set_output(request->input() + 10000);
    if (done) done->Run();
  }

};

void Wait(Test* t, RPC* rpc) {
  LOG(INFO) << rpc->status();
  LOG(INFO) << t->DebugString();
}

Test MakeMessage(int i) {
  Test t;
  t.set_input(i);
  return t;
}

DEFINE_bool(server, false, "");
int main(int argc, char** argv) {
  Init(argc, argv);
  if (FLAGS_server) {
    DefaultExecutor exec(5);
    RpcService service(FLAGS_port, &exec);
    PollRunner runner;
    service.SetPollRunner(&runner);
    CHECK(service.StartListen());
    service.ExportService(new ExampleSearchService());
    runner.Loop();
  }

  ClientPollRunner poll2;
  DefaultExecutor exec(5);
  ClientRpcChannel channel("127.0.0.1", FLAGS_port, &poll2, &exec);
  TestService* service = new TestService::Stub(&channel);
  RPC rpc1;
  Test s1 = MakeMessage(100);
  Test t1;
  service->Search(&rpc1, &s1, &t1, NewCallback(&Wait, &t1, &rpc1));
  RPC rpc2;
  Test s2 = MakeMessage(200);
  Test t2;
  rpc2.set_deadline(6);
  service->Search2(&rpc2, &s2, &t2, NewCallback(&Wait, &t2, &rpc2));
  sleep(30);
}

